package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.service.CommunicatePlanListService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.message.domain.entity.PushEntity;
import com.xbongbong.message.domain.entity.PushSetEntity;
import com.xbongbong.paas.business.rule.RuleBusinessLogger;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.ItemDataPoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.vo.FormDataAddGetVO;
import com.xbongbong.paas.pojo.vo.FormDataDeleteBatchVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.log.crm.help.OperationLogHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.parent.interfaces.DynamicStrategy;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.applist.pojo.MobilePlanStaticPojo;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.applist.pojo.vo.MobilePlanStaticVO;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.businessdata.pojo.dto.HasCommunicatePlanDTO;
import com.xbongbong.pro.communicateplan.pojo.dto.CommunicatePlanDeleteBatchDTO;
import com.xbongbong.pro.communicateplan.pojo.dto.CommunicatePlanUpdateBatchDTO;
import com.xbongbong.pro.communicateplan.pojo.dto.CommunicatePlanUpdateDTO;
import com.xbongbong.pro.communicateplan.pojo.dto.UpdateCommunicatePlanByBusinessRuleDTO;
import com.xbongbong.pro.communicateplan.pojo.vo.CommunicatePlanUpdateBatchVO;
import com.xbongbong.pro.communicateplan.pojo.vo.UpdateCommunicatePlanByBusinessRuleVO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.RangeScreenConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicDeleteDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicSaveDTO;
import com.xbongbong.pro.enums.CommunicatePlanNotifyTypeEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.CommuicatePlanErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainBatchLinkItemDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.fromdatadictionary.pojo.vo.DictionaryArrayVO;
import com.xbongbong.pro.log.pojo.dto.RuleBusinessLogDTO;
import com.xbongbong.pro.message.constant.CommunicatePlanPushConstant;
import com.xbongbong.pro.message.enums.PushObjectTypeEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.message.model.PushSetModel;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.pushset.CommunicatePlanPushSet;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.weblist.pojo.CommunicatePlanStatisicsPojo;
import com.xbongbong.pro.weblist.pojo.SpecialListFieldPojo;
import com.xbongbong.pro.weblist.pojo.dto.CommunicatePlanDTO;
import com.xbongbong.pro.weblist.pojo.dto.CommunicatePlanOperateDTO;
import com.xbongbong.pro.weblist.pojo.dto.CommunicatePlanSearchDTO;
import com.xbongbong.pro.weblist.pojo.dto.DelayCauseDTO;
import com.xbongbong.pro.weblist.pojo.dto.SaasBaseDTO;
import com.xbongbong.pro.weblist.pojo.vo.CommunicatePlanDayListVO;
import com.xbongbong.pro.weblist.pojo.vo.CommunicatePlanSearchVO;
import com.xbongbong.pro.weblist.pojo.vo.CommunicatePlanStatisicsVO;
import com.xbongbong.pro.weblist.pojo.vo.CustomerPlanVO;
import com.xbongbong.pro.weblist.pojo.vo.SpecialListFilterVO;
import com.xbongbong.saas.analytical.impl.CommunicatePlanValidateAnalyticalServiceImpl;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.PageConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CommunicatePlanUserEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.ext.CommunicatePlanEntityExt;
import com.xbongbong.saas.enums.ExecutorCheckBoxEnum;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.dictionary.CommunicatePlanStatusEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.enums.subform.CommunicatePlanTeamEnum;
import com.xbongbong.saas.help.FieldAttrHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.model.CommunicatePlanModel;
import com.xbongbong.saas.model.CommunicatePlanUserModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.service.CommonService;
import com.xbongbong.saas.service.CommunicatePlanService;
import com.xbongbong.saas.service.DictionaryService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.join.query.HasChildQueryBuilder;
import org.elasticsearch.join.query.JoinQueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.ExtendedBounds;
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.IndexBoost;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.paas.elasticsearch.constant.EsNormalConstant.MINI_MUM_SHOULD_MATCH;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 访客计划service层实现层
 *
 * @author long.rao
 * @version v1.0
 * @date 2019/1/22 11:24
 * @since v1.0
 */
@Service("communicatePlanService")
public class CommunicatePlanServiceImpl implements CommunicatePlanService {

    private static final Logger LOG = LoggerFactory.getLogger(CommunicatePlanServiceImpl.class);

    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private CommunicatePlanUserModel communicatePlanUserModel;
    @Resource
    private CommunicatePlanModel communicatePlanModel;
    @Resource
    private UserModel userModel;
    @Resource
    private FieldAttrHelp fieldAttrHelp;
    @Resource
    private DictionaryService dictionaryService;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private PushSetModel pushSetModel;
    @Resource
    private MessageService messageService;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    @Lazy
    private RuleBusinessLogger ruleBusinessLogger;
    @Resource
    private CommunicatePlanValidateAnalyticalServiceImpl communicatePlanAnalyticalService;
    @Resource
    private CommonService commonService;
    @Resource
    private CommunicatePlanListService communicatePlanListService;
    @Resource
    private OperationLogHelp operationLogHelp;
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;

    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private PushModel pushModel;

    private static final Integer STATISTICS_PAGE_SIZE = 5;
    private static final String TREE_TYPE_STAFF = "staff";
    private static final String TREE_TYPE_DEPARTMENT = "department";



    /**
     * 访客计划保存前saas特殊校验
     * @param validateDataDTO saas特殊校验数据入参
     * @throws XbbException 业务异常
     * @author long.rao
     * @date 2019-01-23 10:13
     */
    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        communicatePlanAnalyticalService.beforeSave(validateDataDTO);
    }



    @Override
    public void afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long id = newPaasFormDataEntity.getId();
        String corpid = newPaasFormDataEntity.getCorpid();
        String userId = saasFormSaveDTO.getUserId();
        JSONObject newData = newPaasFormDataEntity.getData();
        Long newCustomerId = FastJsonHelper.getLongOrDefaultFromFormData(newData, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), 0L);
        List<String> userList = saveExecutor2CommunicatePlanUser(newData, CommunicatePlanEnum.EXECUTOR.getAttr(), CommunicatePlanEnum.EXECUTOR_LINKED_TEXT.getAttr(), newCustomerId, corpid, id, userId);

        // TODO 日志

        List<String> pushUserList = new ArrayList<>();
        if (saasFormSaveDTO.getIsNew()) {
            Integer notifyType = getIntegerFromFormData(newData, CommunicatePlanEnum.NOTIFY_TYPE.getAttr());
            if (!Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                // 访客计划新建消息推送
                CommunicatePlanPushSet communicatePlanPushSet = new CommunicatePlanPushSet();
                PushSetEntity pushSetEntity = communicatePlanPushSet.getPushSet(corpid, PushTypeEnum.COMMUNICATE_PLAN_ADD_PUSH.getSubCode(), pushSetModel);
                if (Objects.equals(pushSetEntity.getEnable(), 1)) {
                    String pushObjectString = pushSetEntity.getPushObject();
                    JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectString);
                    String typeString = pushObject.getString("type");
                    JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeString);
                    for (Object object : typeJsonArray) {
                        JSONObject jsonObject = (JSONObject) object;
                        Integer enable = jsonObject.getInteger("enable");
                        if (Objects.equals(enable, 1)) {
                            String alias = jsonObject.getString("alias");
                            if (Objects.equals(alias, PushObjectTypeEnum.EXECUTOR.getAlias())) {
                                pushUserList.addAll(userList);
                            }
                        }
                    }
                    UserVO loginUser = saasFormSaveDTO.getLoginUser();
                    UserEntity userEntity = new UserEntity();
                    BeanUtil.copyProperties(loginUser, userEntity);
                    pushUserList.addAll(pushHelper.getPushUserIdList(userEntity, pushObjectString, pushUserList, DateUtil.getInt()));
                    pushUserList.remove(loginUser.getUserId());
                    PushRefTypePojo.Options options = new PushRefTypePojo.Options(newPaasFormDataEntity.getAppId(), newPaasFormDataEntity.getMenuId(), newPaasFormDataEntity.getFormId(), id, Collections.singletonList(id), SaasMarkEnum.SAAS.getCode(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getSubBusinessType());
                    MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(id), 0, null, I18nMessageUtil.getMessage(CommunicatePlanPushConstant.COMMUNICATE_PLAN_NEW_TITLE), String.format(I18nMessageUtil.getMessage(CommunicatePlanPushConstant.COMMUNICATE_PLAN_NEW_CONTENT), saasFormSaveDTO.getLoginUserName(), newData.getString(CommunicatePlanEnum.NAME.getAttr())), null, options);
                    baseProducer.sendMessage(PushTypeEnum.COMMUNICATE_PLAN_ADD_PUSH, messageRabbitMqDTO);
                }
            }

            if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), saasFormSaveDTO.getDistributorMark())) {
                DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategy(ProjectLogEnum.CUSTOMER_COMMUNICATE_PLAN_CREATE.getSubType());
                dynamicStrategy.save(DynamicSaveDTO.initDynamicSaveDTO(id, newPaasFormDataEntity.getFormId(), saasFormSaveDTO, userModel.getByKeyIngoreDel(userId, corpid), null));
            }
            //访客计划提醒保存(新建访客计划时同时保存消息)
            if (!Objects.equals(notifyType, CommunicatePlanNotifyTypeEnum.NO_NOTIFY.getCode())) {
                pushUserList.clear();
                pushUserList.addAll(userList);
                Long pushTime = newData.getLong(CommunicatePlanEnum.NOTIFY_TIME.getAttr());
                PushRefTypePojo.Options optionsRemind = new PushRefTypePojo.Options(newPaasFormDataEntity.getAppId(), newPaasFormDataEntity.getMenuId(), newPaasFormDataEntity.getFormId(), id, Collections.singletonList(id), SaasMarkEnum.SAAS.getCode(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getSubBusinessType());
                MessageRabbitMqDTO messageRabbitMqDTORemind = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(id), 1, pushTime, newData.getString(CommunicatePlanEnum.NAME.getAttr()), newData.getString(CommunicatePlanEnum.MEMO.getAttr()), null, optionsRemind);
                messageService.insertPushData(messageRabbitMqDTORemind, PushTypeEnum.COMMUNICATE_PLAN_PUSH);
            }

        }
    }



    @Override
    public CommunicatePlanDayListVO dayList(CommunicatePlanDTO communicatePlanDTO) throws XbbException {
        // 返回类型
        if (Objects.equals(communicatePlanDTO.getFromIndex(),BasicConstant.ONE)){
            communicatePlanDTO.setListGroupId(ListGroupEnum.COMMUNICATE_PLAN_RESPONSIBLE.getCode());
        }
        List<ConditionsEntityExt> conditionsEntityExtList = setConditionList(communicatePlanDTO);
        //创建时间(区间)
        ConditionsEntityExt dateCondition = new ConditionsEntityExt();
        Long dateInt;
        try {
            String date = communicatePlanDTO.getDate();
            dateInt = StringUtil.isEmpty(date) ? DateTimeUtil.getTodayInt() : DateTimeUtil.getInt(date, new SimpleDateFormat("yyyy-MM-dd"));
        }catch (Exception e){
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214006);
        }
        dateCondition.setAttr(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr());
        dateCondition.setFieldType(CommunicatePlanEnum.COMMUNICATE_TIME.getFieldType());
        dateCondition.setName(CommunicatePlanEnum.COMMUNICATE_TIME.getAttrName());
        dateCondition.setSymbol(ConditionEnum.RANGE.getSymbol());
//        Long startTime = DateTimeUtil.getFirstDateOfMonthInSomeday(dateInt);
//        Long endTime = DateTimeUtil.getLastDateOfMonthInSomeday(dateInt);
        // 时间范围改成上个月1号零点到下两个月1号零点
        Long startTime = DateTimeUtil.getFirstDateOfLastMonth(dateInt);
        Long endTime = DateTimeUtil.getLastDateOfNextMonthInSomeday(dateInt);
        dateCondition.setValue(Arrays.asList(startTime,endTime));
        conditionsEntityExtList.add(dateCondition);
        // 返回类型
        if (Objects.equals(communicatePlanDTO.getFromIndex(),BasicConstant.ONE)){
            ConditionsEntityExt typeCondition = new ConditionsEntityExt();
            typeCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
            typeCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
            typeCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
            typeCondition.setSymbol(ConditionEnum.IN.getSymbol());
            typeCondition.setValue(Arrays.asList(CommunicatePlanStatusEnum.NO_FOLLOW.getCode(),CommunicatePlanStatusEnum.DELAY.getCode()));
            conditionsEntityExtList.add(typeCondition);
        }
        JSONObject result = esDayList(communicatePlanDTO.getCorpid(),conditionsEntityExtList,startTime,endTime,communicatePlanDTO);
        Set<String> dayList = analysisDayList(result);
        CommunicatePlanDayListVO communicatePlanDayListVO = new CommunicatePlanDayListVO();
        communicatePlanDayListVO.setHasPlanDayArray(dayList);
        return communicatePlanDayListVO;
    }

    /**
     * 解析es聚合数据
     * @param result 聚合数据
     * @return 有计划的日期
     */
    private Set<String> analysisDayList(JSONObject result) {
        Set<String> dayList = new HashSet<>();
        JSONArray buckets =  result.getJSONObject("aggregations").getJSONObject("aggs01").getJSONArray("buckets");
        for (Object obj : buckets){
            JSONObject json = (JSONObject) obj;
            if (json.getInteger("doc_count") != null && json.getInteger("doc_count") > 0){
                dayList.add(json.getString("key_as_string"));
            }
        }
        return dayList;
    }

    @Override
    public CommunicatePlanStatisicsVO statistics(CommunicatePlanDTO communicatePlanDTO) throws XbbException {
        List<ConditionsEntityExt> conditionsEntityExtList = setConditionList(communicatePlanDTO);
        // 父子文档查询参数
        Set<String> subUserIds = setTeamCondition(communicatePlanDTO, conditionsEntityExtList);
        List<PaasFormDataEntityExt> list = getStatisticsEsList(communicatePlanDTO, conditionsEntityExtList);
        List<Long> planIdList = new ArrayList<>();
        for (PaasFormDataEntityExt entity : list){
            planIdList.add(entity.getDataId());
        }
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",communicatePlanDTO.getCorpid());
        map.put("planIdIn",planIdList);
        map.put("del",0);
        List<CommunicatePlanUserEntity> communicatePlanUserEntityList = planIdList.isEmpty() ? new ArrayList<>() : communicatePlanUserModel.findEntitys(map);
        communicatePlanUserEntityList = handlePlanUser(communicatePlanUserEntityList, communicatePlanDTO);
        List<String> userList = new ArrayList<>();
        HashSet<String> userSet = new LinkedHashSet<>();
        Integer page = communicatePlanDTO.getPage() == null ? 1 : communicatePlanDTO.getPage();
        Map<String,List<Long>> userPlanMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (CommunicatePlanUserEntity entity : communicatePlanUserEntityList){
            //需要分页则判断分页
            String userId = entity.getUserId();
            if (!subUserIds.contains(userId)) {
                continue;
            }
            userSet.add(userId);
            List<String> localUserList = new ArrayList<>(userSet);
            if (localUserList.indexOf(userId) < (page - 1) * STATISTICS_PAGE_SIZE) {
                continue;
            }
            if (localUserList.indexOf(userId) >= page * STATISTICS_PAGE_SIZE) {
                continue;
            }
            List<Long> userPlanIdList;
            userPlanIdList = userPlanMap.getOrDefault(userId,new ArrayList<>());
            userPlanIdList.add(entity.getDataId());
            userPlanMap.put(entity.getUserId(),userPlanIdList);
            userList.add(userId);
        }
        Map<String,String> userMap = userList.isEmpty() ? new HashMap<>() : userModel.getUserNameMap(communicatePlanDTO.getCorpid(),userList);
        Map<String,Integer> finishMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Integer> notFinishMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Integer> cancelhMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Integer> delayMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String statusAttr = CommunicatePlanEnum.STATUS.getAttr();
        for (Map.Entry<String,List<Long>> entry : userPlanMap.entrySet()){
            String userId = entry.getKey();
            List<Long> localPlanIdList = entry.getValue();
            for (PaasFormDataEntityExt entity : list){
                if (!localPlanIdList.contains(entity.getDataId())){
                    continue;
                }
                Integer status = entity.getData().getInteger(statusAttr);
                if (Objects.equals(String.valueOf(status),CommunicatePlanStatusEnum.FINISH.getCode())) {
                    finishMap.put(userId,finishMap.getOrDefault(userId,0) + 1);
                }else if (Objects.equals(String.valueOf(status),CommunicatePlanStatusEnum.CANCEL.getCode())){
                    cancelhMap.put(userId,cancelhMap.getOrDefault(userId,0) + 1);
                }else if (Objects.equals(entity.getData().getInteger(CommunicatePlanEnum.IS_DELAY.getAttr()),1)){
                    delayMap.put(userId,delayMap.getOrDefault(userId,0) + 1);
                }else if (Objects.equals(String.valueOf(status),CommunicatePlanStatusEnum.NO_FOLLOW.getCode())){
                    notFinishMap.put(userId,notFinishMap.getOrDefault(userId,0) + 1);
                }
            }
        }
        CommunicatePlanStatisicsVO communicatePlanStatisicsVO = new CommunicatePlanStatisicsVO();
        List<CommunicatePlanStatisicsPojo> communicatePlanStatisicsPojoList = new ArrayList<>();
        for (Map.Entry<String,String> entry : userMap.entrySet()){
            CommunicatePlanStatisicsPojo communicatePlanStatisicsPojo = new CommunicatePlanStatisicsPojo();
            String userId = entry.getKey();
            communicatePlanStatisicsPojo.setUserId(userId);
            communicatePlanStatisicsPojo.setUserName(entry.getValue());
            communicatePlanStatisicsPojo.setFinishPlanCount(finishMap.getOrDefault(userId, 0));
            communicatePlanStatisicsPojo.setNotFinishPlanCount(notFinishMap.getOrDefault(userId, 0));
            communicatePlanStatisicsPojo.setCancelCount(cancelhMap.getOrDefault(userId, 0));
            communicatePlanStatisicsPojo.setDelayCount(delayMap.getOrDefault(userId, 0));
            communicatePlanStatisicsPojoList.add(communicatePlanStatisicsPojo);
        }
        communicatePlanStatisicsVO.setStatisticsArray(communicatePlanStatisicsPojoList);
        UserEntity userEntity = userModel.getByKey(communicatePlanDTO.getUserId(),communicatePlanDTO.getCorpid());
        Boolean isBoss = userEntity.isOriAdmin();
        communicatePlanStatisicsVO.setIsBoss(isBoss);

        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), null);
        communicatePlanStatisicsVO.setDataPermission(Objects.equals(dataPermission,1) ? 0 : 1);
        if (Objects.equals(communicatePlanStatisicsVO.getDataPermission(), 0) && communicatePlanStatisicsPojoList.size() > 0){
            Integer index = 0;
            for (CommunicatePlanStatisicsPojo planStatisicsPojo : communicatePlanStatisicsPojoList) {
                if (Objects.equals(planStatisicsPojo.getUserId(), communicatePlanDTO.getUserId())){
                    break;
                }
                index ++;
            }
            Collections.swap(communicatePlanStatisicsPojoList, index, 0);
        }

        PageHelper pageHelper = new PageHelper(page, STATISTICS_PAGE_SIZE);
        pageHelper.setRowsCount(userSet.size());
        communicatePlanStatisicsVO.setPageHelper(pageHelper);
        return communicatePlanStatisicsVO;
    }

    @Override
    public MobilePlanStaticVO mobileStatistics(CommunicatePlanDTO communicatePlanDTO) throws XbbException {
        List<ConditionsEntityExt> conditionsEntityExtList = setConditionList(communicatePlanDTO);
        // 父子文档查询参数
        Set<String> subUserIds = setTeamCondition(communicatePlanDTO, conditionsEntityExtList);
        List<PaasFormDataEntityExt> list = getStatisticsEsList(communicatePlanDTO, conditionsEntityExtList);
        List<Long> planIdList = new ArrayList<>();
        for (PaasFormDataEntityExt entity : list){
            planIdList.add(entity.getDataId());
        }
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",communicatePlanDTO.getCorpid());
        map.put("planIdIn",planIdList);
        map.put("del",0);
        List<CommunicatePlanUserEntity> communicatePlanUserEntityList = planIdList.isEmpty() ? new ArrayList<>() : communicatePlanUserModel.findEntitys(map);
        List<String> userList = new ArrayList<>();
        HashSet<String> userSet = new LinkedHashSet<>();
        Integer page = communicatePlanDTO.getPage() == null ? 1 : communicatePlanDTO.getPage();
        Map<String,List<Long>> userPlanMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (CommunicatePlanUserEntity entity : communicatePlanUserEntityList){
            //需要分页则判断分页
            String userId = entity.getUserId();
            if (!subUserIds.contains(userId)) {
                continue;
            }
            userSet.add(userId);
//            List<String> localUserList = new ArrayList<>(userSet);
//            if (localUserList.indexOf(userId) < (page - 1) * STATISTICS_PAGE_SIZE) {
//                continue;
//            }
//            if (localUserList.indexOf(userId) >= page * STATISTICS_PAGE_SIZE) {
//                continue;
//            }
            List<Long> userPlanIdList;
            userPlanIdList = userPlanMap.getOrDefault(userId,new ArrayList<>());
            userPlanIdList.add(entity.getDataId());
            userPlanMap.put(entity.getUserId(),userPlanIdList);
            userList.add(userId);
        }
        Map<String,String> userMap = userList.isEmpty() ? new HashMap<>() : userModel.getUserNameMap(communicatePlanDTO.getCorpid(),userList);
        Map<String,Integer> finishMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Integer> planMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Integer> notFinishMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Integer> delayMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String statusAttr = CommunicatePlanEnum.STATUS.getAttr();
        for (Map.Entry<String,List<Long>> entry : userPlanMap.entrySet()){
            String userId = entry.getKey();
            List<Long> localPlanIdList = entry.getValue();
            for (PaasFormDataEntityExt entity : list){
                if (!localPlanIdList.contains(entity.getDataId())){
                    continue;
                }
                String status = FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), statusAttr, CommunicatePlanStatusEnum.NO_FOLLOW.getCode());
                if (Objects.equals(status,CommunicatePlanStatusEnum.FINISH.getCode())) {
                    finishMap.put(userId, finishMap.getOrDefault(userId,0) + 1);
                }
                planMap.put(userId, planMap.getOrDefault(userId,0) + 1);
            }
        }
        MobilePlanStaticVO mobilePlanStaticVO = new MobilePlanStaticVO();
        List<MobilePlanStaticPojo> mobilePlanStaticPojoList = new ArrayList<>();
        for (Map.Entry<String,String> entry : userMap.entrySet()){
            MobilePlanStaticPojo mobilePlanStaticPojo = new MobilePlanStaticPojo();
            String userId = entry.getKey();
            Integer planCount = planMap.getOrDefault(userId, 0);
            Integer finishPlanCount = finishMap.getOrDefault(userId, 0);
            Double finishRatio = planCount == 0 ? 0 : Arith.mul(Arith.div(finishPlanCount, planCount, 2), 100);
            mobilePlanStaticPojo.setUserId(userId);
            mobilePlanStaticPojo.setUserName(entry.getValue());
            mobilePlanStaticPojo.setPlanCount(planCount);
            mobilePlanStaticPojo.setFinishPlanCount(finishPlanCount);
            mobilePlanStaticPojo.setFinishPlanRatio(finishRatio.intValue() + "%");
            mobilePlanStaticPojoList.add(mobilePlanStaticPojo);
        }
        mobilePlanStaticVO.setStatisticsArray(mobilePlanStaticPojoList);
        UserEntity userEntity = userModel.getByKey(communicatePlanDTO.getUserId(),communicatePlanDTO.getCorpid());
        Boolean isBoss = userEntity.isOriAdmin();
        mobilePlanStaticVO.setIsBoss(isBoss);
        mobilePlanStaticVO.setDataPermission(isBoss ? 1 : 0);
        PageHelper pageHelper = new PageHelper(page, STATISTICS_PAGE_SIZE);
        pageHelper.setRowsCount(userSet.size());
        mobilePlanStaticVO.setPageHelper(pageHelper);
        return mobilePlanStaticVO;
    }

    @Override
    public CustomerPlanVO list(CommunicatePlanDTO communicatePlanDTO) throws XbbException {
        return communicatePlanListService.list(communicatePlanDTO);
    }

    @Override
    public CommunicatePlanSearchVO getFuzzyQueryList(CommunicatePlanSearchDTO communicatePlanSearchDTO) throws XbbException {
        CommunicatePlanSearchVO communicatePlanSearchVO = new CommunicatePlanSearchVO();
        if ( StringUtil.isEmpty(communicatePlanSearchDTO.getCheckValue())){
            List<ItemDataPoJo> itemList = new ArrayList<>();
            communicatePlanSearchVO.setItems(itemList);
            return communicatePlanSearchVO;
        }
        String corpid = communicatePlanSearchDTO.getCorpid();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid ));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        boolQueryBuilder.should(matchPhraseQuery("data." + CustomerManagementEnum.NAME.getAttr(),communicatePlanSearchDTO.getCheckValue()));
        boolQueryBuilder.should(matchPhraseQuery("data." + CustomerManagementEnum.PHONE.getAttr() + ".text_2",communicatePlanSearchDTO.getCheckValue()));
        boolQueryBuilder.minimumShouldMatch(MINI_MUM_SHOULD_MATCH);
        int page = PageConstant.DEFAULT_INDEX_PAGE - 1;
        int pageSize = PageConstant.DEFAULT_PAGE_SIZE_SMALL;
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, (page - 1), pageSize);
        IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        sourceBuilder.query(boolQueryBuilder);
        // 分页，取前十条
        sourceBuilder.from(page);
        sourceBuilder.size(pageSize);
        SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        List<PaasFormDataEntityExt> formDataEntityExtList = esEntities.getContent();
        List<ItemDataPoJo> itemList = new ArrayList<>();
        if (CollectionsUtil.isEmpty(formDataEntityExtList)){
            communicatePlanSearchVO.setItems(itemList);
            return communicatePlanSearchVO;
        }
        for (PaasFormDataEntityExt paasFormDataEntityExt : formDataEntityExtList) {
            ItemDataPoJo itemDataPoJo = new ItemDataPoJo();
            JSONObject data = paasFormDataEntityExt.getData();
            String customerName =(String) data.getOrDefault(CustomerManagementEnum.NAME.getAttr(), "");
            itemDataPoJo.setText(customerName);
            itemDataPoJo.setValue(paasFormDataEntityExt.getId());
            itemList.add(itemDataPoJo);
        }
        communicatePlanSearchVO.setItems(itemList);
        return communicatePlanSearchVO;
    }

    @Override
    public UpdateCommunicatePlanByBusinessRuleVO updateFormDataByBusinessRule(UpdateCommunicatePlanByBusinessRuleDTO update) throws XbbException {
        UpdateCommunicatePlanByBusinessRuleVO updateCommunicatePlanByBusinessRuleVO = new UpdateCommunicatePlanByBusinessRuleVO();
        try {
            String corpid = update.getCorpid();
            List<PaasFormDataEntityExt> formDataList = update.getFormDataList();
            List<UpdateDataEntity> updateList = ExplainUtil.getUpdateValueByBusinessRule(update.getFormDataList(), corpid, update.getOperations());

            if(!updateList.isEmpty()){
                communicatePlanModel.updateBatch(updateList, corpid);
                RuleBusinessLogDTO businessLogDTO = new RuleBusinessLogDTO();
                BeanUtil.copyProperties(update, businessLogDTO);
                businessLogDTO.setFormDataList(formDataList);
                ruleBusinessLogger.writeLog(businessLogDTO, updateList);
            }
        }catch (Exception e){
            LOG.error("communicatePlanModel.updateFormDataByBusinessRule根据业务规则更新数据出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return updateCommunicatePlanByBusinessRuleVO;
    }

    @Override
    public SpecialListFilterVO statusSearch(SaasBaseDTO saasBaseDTO) throws XbbException{
        SpecialListFilterVO specialListFilterVO = new SpecialListFilterVO();
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(saasBaseDTO.getFormId(), saasBaseDTO.getCorpid());
        if (Objects.isNull(explainEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        // 设置范围筛选
        List<SpecialListFieldPojo> fieldList = new ArrayList<>();
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explainEntity.getExplains(), CommunicatePlanEnum.EXECUTOR.getAttr());
        SpecialListFieldPojo rangeScreenPojo = new SpecialListFieldPojo();
        FieldAttrEntity fieldAttrEntity = explainMap.get(CommunicatePlanEnum.EXECUTOR.getAttr());
        rangeScreenPojo.setAttr(RangeScreenConstant.RANGE_SCREEN);
        rangeScreenPojo.setAttrName(FieldTypeEnum.RANGE_SCREEN.getDescription());
        rangeScreenPojo.setFieldType(FieldTypeEnum.RANGE_SCREEN.getType());
        rangeScreenPojo.setMultiple(0);
        rangeScreenPojo.setPlaceholder(I18nMessageUtil.getMessage(RangeScreenConstant.SELECT));
        List<ItemPoJo> itemPoJoLists = new ArrayList<>();
        ItemPoJo itemPoJo = new ItemPoJo();
        itemPoJo.setText(fieldAttrEntity.getAttrName());
        itemPoJo.setAttr(fieldAttrEntity.getAttr());
        itemPoJoLists.add(itemPoJo);
        rangeScreenPojo.setItems(itemPoJoLists);
        fieldList.add(rangeScreenPojo);
        // 设置计划状态筛选
        List<CommunicatePlanStatusEnum> communicatePlanStatusEnumList = CommunicatePlanStatusEnum.getList();
        StringBuilder valueBuilder = new StringBuilder();
        for (CommunicatePlanStatusEnum statusEnum : communicatePlanStatusEnumList){
            StringUtil.stringBuilderAppendSuffix(valueBuilder,",",statusEnum.getAlias());
        }
        List<ItemPoJo> itemPoJoList = fieldAttrHelp.initItem(valueBuilder.toString());
        SpecialListFieldPojo specialListFieldPojo = new SpecialListFieldPojo();
        specialListFieldPojo.setAttr(CommunicatePlanEnum.STATUS.getSaasAttr());
        specialListFieldPojo.setAttrName(CommunicatePlanEnum.STATUS.getAttrName());
        specialListFieldPojo.setFieldType(FieldTypeEnum.COMBO.getType());
        specialListFieldPojo.setMultiple(0);
        specialListFieldPojo.setPlaceholder(I18nMessageUtil.getMessage(I18nStringConstant.SELECT_PLAN_STATUS));
        specialListFieldPojo.setItems(itemPoJoList);
        fieldList.add(specialListFieldPojo);
        // 设置关联客户筛选
        SpecialListFieldPojo customerPojo = new SpecialListFieldPojo();
        customerPojo.setAttr("nameLike");
        customerPojo.setAttrName(WorkOrderEnum.LINK_CUSTOMER.getAttrName());
        customerPojo.setFieldType(FieldTypeEnum.TEXT.getType());
        customerPojo.setPlaceholder(I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_NAME_OR_PHONE_SEARCH));
        fieldList.add(customerPojo);
        specialListFilterVO.setFieldList(fieldList);
        return specialListFilterVO;
    }

    @Override
    public BaseVO singleOperate(CommunicatePlanOperateDTO communicatePlanOperateDTO) throws XbbException {
        String operate = communicatePlanOperateDTO.getOperate();
        CommunicatePlanStatusEnum communicatePlanStatusEnum = CommunicatePlanStatusEnum.getByCode(operate.toString());
        CommunicatePlanEntityExt communicatePlanEntityExt = communicatePlanModel.getByKey(communicatePlanOperateDTO.getDataId(),communicatePlanOperateDTO.getCorpid());
        CommunicatePlanEntityExt oldCommunicatePlanEntityExt = (CommunicatePlanEntityExt)CloneUtil.deepClone(communicatePlanEntityExt);
        if (communicatePlanEntityExt == null || communicatePlanEntityExt.getDel() == 1){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }
        JSONObject data = communicatePlanEntityExt.getData();
        switch (communicatePlanStatusEnum){
            case FINISH:
                UserEntity userEntity = userModel.getByKey(communicatePlanOperateDTO.getUserId(),communicatePlanOperateDTO.getCorpid());
                data.put(CommunicatePlanEnum.FINISH_TIME.getAttr(),DateUtil.getInt());
                data.put(CommunicatePlanEnum.FINISH_USER_ID.getAttr(),userEntity.getUserId());
                data.put(CommunicatePlanEnum.FINISH_USER_NAME.getAttr(),userEntity.getName());
                data.put(CommunicatePlanEnum.FINISH_USER_AVATAR.getAttr(),userEntity.getAvatar());
                data.put(CommunicatePlanEnum.STATUS.getAttr(),operate);
                communicatePlanEntityExt.setData(data);
                break;
            case DELAY:
                Integer delayTime = communicatePlanOperateDTO.getDelayTime();
                String delayMemo = communicatePlanOperateDTO.getDelayMemo();
                Integer delayCause = communicatePlanOperateDTO.getDelayCause();
                if (delayTime < DateUtil.getInt()){
                    throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214005);
                }
                //延期访客计划重新计算提醒时间
                Integer notifyType = getIntegerOrDefaultFromFormData(data, CommunicatePlanEnum.NOTIFY_TYPE.getAttr(), CommunicatePlanNotifyTypeEnum.NO_NOTIFY.getCode());
                Long notifyTime = FastJsonHelper.getLongFromFormData(data, CommunicatePlanEnum.NOTIFY_TIME.getAttr());
                notifyTime = communicatePlanAnalyticalService.checkCommunicateTime(delayTime.longValue(), notifyType, notifyTime);
                if (notifyType.equals(CommunicatePlanNotifyTypeEnum.NO_NOTIFY.getCode())) {
                    notifyTime = null;
                }
                data.put(CommunicatePlanEnum.NOTIFY_TIME.getAttr(), notifyTime);
                data.put(CommunicatePlanEnum.IS_DELAY.getAttr(),1);
                data.put(CommunicatePlanEnum.ORI_COMMUNICATE_TIME.getAttr(), data.get(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr()));
                data.put(CommunicatePlanEnum.DELAY_CAUSE.getAttr(),delayCause);
                data.put(CommunicatePlanEnum.DELAY_MEMO.getAttr(),delayMemo);
                data.put(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr(),delayTime);
                data.put(CommunicatePlanEnum.STATUS.getAttr(),operate);
                communicatePlanEntityExt.setData(data);
                break;
            case CANCEL:
                data.put(CommunicatePlanEnum.STATUS.getAttr(),operate);
                communicatePlanEntityExt.setData(data);
                break;
            default:
                break;
        }
        communicatePlanEntityExt.setUpdateTime((long) DateUtil.getInt());
        communicatePlanModel.update(communicatePlanEntityExt);
        boolean deletePushFalg = communicatePlanStatusEnum == CommunicatePlanStatusEnum.FINISH || communicatePlanStatusEnum == CommunicatePlanStatusEnum.CANCEL;
        if (deletePushFalg) {
            deletePush(communicatePlanOperateDTO.getCorpid(), Collections.singletonList(communicatePlanOperateDTO.getDataId()));
        }
        // 日志
        operationLogHelp.updateCommunicatePlanLog(communicatePlanOperateDTO,communicatePlanEntityExt,oldCommunicatePlanEntityExt);

        return new BaseVO();
    }

    @Override
    public DictionaryArrayVO getDelayCauseDataDictionary(DelayCauseDTO delayCauseDTO) throws XbbException {
        if (Objects.isNull(delayCauseDTO.getFormId()) || Objects.equals(delayCauseDTO.getFormId(), 0L)) {
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(delayCauseDTO.getBusinessType(), delayCauseDTO.getCorpid());
            delayCauseDTO.setFormId(paasFormExplainEntity.getFormId());
        }
        List<ItemPoJo> list = dictionaryService.getArrayList(DictionaryEnum.DELAY_CAUSE,delayCauseDTO.getCorpid(),delayCauseDTO.getFormId());
        DictionaryArrayVO dictionaryArrayVO = new DictionaryArrayVO();
        dictionaryArrayVO.setList(list);
        return dictionaryArrayVO;
    }

    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, CommunicatePlanEnum.NOTIFY_TIME.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo = fieldAttrEntity.getSaasParticularAttributePoJo();
                saasParticularAttributePoJo = saasParticularAttributePoJo == null ? new SaasParticularAttributePoJo() : saasParticularAttributePoJo;
                saasParticularAttributePoJo.setDateLimit(DateTimeUtil.getTodayInt());
                saasParticularAttributePoJo.setLimitType(false);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            }
        }
    }

    @Override
    public void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        JSONArray linkCustomerArray = new JSONArray();
        Integer linkBusinessType = handlerExplainInLinkItemDTO.getLinkBusinessType();
        JSONObject linkFormData = handlerExplainInLinkItemDTO.getLinkFormData();
        List<FieldAttrEntity> explainList = handlerExplainInLinkItemDTO.getExplainList();
        PaasFormDataEntityExt paasFormDataEntityExt = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt();
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(linkBusinessType);
        switch (redundantTemplateTypeEnum) {
            case CUSTOMER:
                    JSONObject customerObj = new JSONObject();
                    customerObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, paasFormDataEntityExt.getId());
                    customerObj.put(StringConstant.SAAS_LINK_BUSINESS_NAME, FastJsonHelper.getStringOrDefaultFromFormData(paasFormDataEntityExt.getData(), CustomerManagementEnum.NAME.getAttr(), ""));
                    linkCustomerArray.add(customerObj);
                break;
            default:
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }
        String customerName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, CustomerManagementEnum.NAME.getAttr(), "");
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), CommunicatePlanEnum.NAME.getAttr())) {
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
                fieldAttrEntity.setDefaultAttr(saasUpdateHelp.setDefaultValue(customerName + I18nMessageUtil.getMessage(I18nStringConstant.COMMUNICATE_PLAN)));
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), CommunicatePlanEnum.LINK_CUSTOMER.getAttr())) {
                fieldAttrEntity.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkCustomerArray));
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), CommunicatePlanEnum.COMMUNICATE_TIME.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                saasParticularAttributePoJo.setDateLimit(DateTimeUtil.getTodayInt());
                saasParticularAttributePoJo.setLimitType(false);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            }
        }
    }

    @Override
    public void formatBatchLinkAddExplain(HandlerExplainBatchLinkItemDTO handlerExplainBatchLinkItemDTO) throws XbbException {
        JSONArray linkCustomerArray = new JSONArray();
        Integer linkBusinessType = handlerExplainBatchLinkItemDTO.getLinkBusinessType();
        List<FieldAttrEntity> explainList = handlerExplainBatchLinkItemDTO.getExplainList();
        List<PaasFormDataEntityExt> paasFormDataEntityExts = handlerExplainBatchLinkItemDTO.getPaasFormDataEntityExts();
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(linkBusinessType);
        switch (redundantTemplateTypeEnum) {
            case CUSTOMER:
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                    JSONObject customerObj = new JSONObject();
                    customerObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, paasFormDataEntityExt.getId());
                    customerObj.put(StringConstant.SAAS_LINK_BUSINESS_NAME, FastJsonHelper.getStringOrDefaultFromFormData(paasFormDataEntityExt.getData(), CustomerManagementEnum.NAME.getAttr(), ""));
                    linkCustomerArray.add(customerObj);
                }
                break;
            default:
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), CommunicatePlanEnum.NAME.getAttr())) {
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
                fieldAttrEntity.setDefaultAttr(saasUpdateHelp.setDefaultValue(I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_COMMUNICATE_PLAN)));
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), CommunicatePlanEnum.LINK_CUSTOMER.getAttr())) {
                fieldAttrEntity.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkCustomerArray));
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), CommunicatePlanEnum.COMMUNICATE_TIME.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo = new SaasParticularAttributePoJo();
                saasParticularAttributePoJo.setDateLimit(DateTimeUtil.getTodayInt());
                saasParticularAttributePoJo.setLimitType(false);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            }
        }
    }


    @Override
    public FormDataDeleteBatchVO deleteBatch(CommunicatePlanDeleteBatchDTO communicatePlanDeleteBatchDTO) throws XbbException {
        FormDataDeleteBatchVO formDataDeleteBatchVO = new FormDataDeleteBatchVO();
        try {
            List<Long> idIn = communicatePlanDeleteBatchDTO.getDataIdList();
            String corpid = communicatePlanDeleteBatchDTO.getCorpid();
            List<String> name= new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<PaasFormDataEntityExt> noList = new ArrayList<>(0);
            if (!idIn.isEmpty()) {
                //查询名称
                BoolQueryBuilder builder = boolQuery();
                // 添加corpid,formId,del
                builder.filter(termQuery("corpid.keyword", corpid));
                builder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
                builder.filter(termsQuery(StringConstant.DATA_ID, idIn));
                List<String> fieldList = new ArrayList<>();
                fieldList.add(FieldTypeEnum.SERIALNO.getAlias());
                fieldList.add(CommunicatePlanEnum.getAttrConnectData(CommunicatePlanEnum.NAME));
                fieldList.add(CommunicatePlanEnum.getAttrConnectData(CommunicatePlanEnum.LINK_CUSTOMER));
                noList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN, builder, PaasFormDataEntityExt.class, fieldList);
                for(PaasFormDataEntityExt entityExt : noList){
                    JSONObject data = entityExt.getData();
                    String sheetName = FastJsonHelper.getStringOrDefaultFromFormData(data, CommunicatePlanEnum.NAME.getAttr(), "");
                    name.add(sheetName);
                }
                if(BasicConstant.ONE.equals(communicatePlanDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(idIn.size())){
                    communicatePlanModel.deleteByKey(idIn.get(0),corpid);
                }else {
                    communicatePlanModel.deleteBatch(idIn, corpid);
                }
                formDataDeleteBatchVO.setDeleteIds(idIn);
                deletePush(corpid, idIn);
            }
            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            if (Objects.equals(1, communicatePlanDeleteBatchDTO.getIsBusinessRule())) {
                operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            }

            // 动态
            try {
                if(!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(),communicatePlanDeleteBatchDTO.getDistributorMark())) {
                    DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategy(ProjectLogEnum.CUSTOMER_COMMUNICATE_PLAN_DELETE.getSubType());
                    List<PaasFormDataEntityExt> allowDeletePaasFormDatas = new ArrayList<>(idIn.size());
                    BeanUtil.copyPropertiesList(noList, allowDeletePaasFormDatas, PaasFormDataEntityExt.class);
                    FormDataDeleteBatchDTO formDataDeleteBatchDTO = BeanUtil.copyProperties(communicatePlanDeleteBatchDTO, FormDataDeleteBatchDTO.class, true);
                    dynamicStrategy.batchDelete(DynamicDeleteDTO.initDynamicDeleteDTO(formDataDeleteBatchDTO, idIn, allowDeletePaasFormDatas));
                }
            } catch (Exception e) {
                LOG.error("删除访客计划动态失败：", e);
            }

            //生成删除日志(区分单个删除和批量删除)
            String userId = communicatePlanDeleteBatchDTO.getUserId();
            String userName = communicatePlanDeleteBatchDTO.getLoginUserName();
            String nameStr = StringUtils.join(name, "，");
            if(idIn.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.COMMUNICATE_PLAN.getName(), idIn.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(CommunicatePlanEnum.NAME.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.CommunicatePlan, operateTypeEnum,
                        "", "", memo, communicatePlanDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(idIn.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.COMMUNICATE_PLAN.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.CommunicatePlan, operateTypeEnum,
                        idIn.get(0).toString(), nameStr, memo, communicatePlanDeleteBatchDTO.getHttpHeader());
            }
        } catch (Exception e) {
            LOG.error("supplierCommunicateServiceImpl.deleteBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formDataDeleteBatchVO;
    }

    /**
     * 设置查询条件
     * @param communicatePlanDTO 参数
     * @return 查询条件
     */
    @Override
    public List<ConditionsEntityExt> setConditionList(CommunicatePlanDTO communicatePlanDTO) throws XbbException{
        List<ConditionsEntityExt> conditionsEntityExtList = new ArrayList<>();
        rangeScreen(communicatePlanDTO, conditionsEntityExtList);
        // 访客计划模糊查询，查的是客户名称或电话
        String nameLike = communicatePlanDTO.getNameLike();
        List<Object> customerId = new ArrayList<>();
        if (nameLike != null && !StringUtil.isEmpty(nameLike, true)) {
            BoolQueryBuilder nameLikeQuery = boolQuery();
            nameLikeQuery.filter(termQuery("corpid.keyword", communicatePlanDTO.getCorpid()));
            nameLikeQuery.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            EsUtil.setNameLike(SaasMarkEnum.SAAS.getCode(), nameLike, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), false, nameLikeQuery,true,null,null);

            IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(communicatePlanDTO.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

            List<PaasFormDataEntityExt> customerList = esHelper.findByScroll(indexTypeEnum,nameLikeQuery,PaasFormDataEntityExt.class,Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
            customerList.forEach(item ->{
                customerId.add(item.getDataId());
            });
            if (!customerId.isEmpty()) {
                conditionsEntityExtList.add(EsUtil.packageContions(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), customerId, ConditionEnum.IN, CommunicatePlanEnum.LINK_CUSTOMER.getFieldType()));
            } else {
                conditionsEntityExtList.add(EsUtil.packageContions(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), Collections.singletonList(-1L), ConditionEnum.EQUAL, CommunicatePlanEnum.LINK_CUSTOMER.getFieldType()));
            }
        }
        String customerId1 = communicatePlanDTO.getCustomerId();
        //访客计划模糊查询优化--->精确匹配（有家公司数据量过大，导出报错）
        if (customerId1 != null && !StringUtil.isEmpty(customerId1, true)) {
            List<Object> customerIds = Arrays.asList(customerId1);
            conditionsEntityExtList.add(EsUtil.packageContions(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), customerIds, ConditionEnum.IN, CommunicatePlanEnum.LINK_CUSTOMER.getFieldType()));
        }
        //访客计划状态
        CommunicatePlanStatusEnum statusEnum = CommunicatePlanStatusEnum.getByCode(Objects.toString(communicatePlanDTO.getStatus(),""));
        ConditionsEntityExt statusCondition = new ConditionsEntityExt();
        ConditionsEntityExt delayCondition = new ConditionsEntityExt();
        switch (statusEnum){
            case NO_FOLLOW:
                statusCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
                statusCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
                statusCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
                statusCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                statusCondition.setValue(Collections.singletonList((statusEnum.getCode().toString())));
                delayCondition.setAttr(CommunicatePlanEnum.IS_DELAY.getAttr());
                delayCondition.setFieldType(CommunicatePlanEnum.IS_DELAY.getFieldType());
                delayCondition.setName(CommunicatePlanEnum.IS_DELAY.getAttrName());
                delayCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                delayCondition.setValue(Collections.singletonList(0));
                conditionsEntityExtList.add(statusCondition);
                conditionsEntityExtList.add(delayCondition);
                break;
            case FINISH:
                statusCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
                statusCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
                statusCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
                statusCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                statusCondition.setValue(Collections.singletonList((statusEnum.getCode().toString())));
                conditionsEntityExtList.add(statusCondition);
                break;
            case CANCEL:
                statusCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
                statusCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
                statusCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
                statusCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                statusCondition.setValue(Collections.singletonList((statusEnum.getCode().toString())));
                conditionsEntityExtList.add(statusCondition);
                break;
            case DELAY:
                statusCondition.setAttr(CommunicatePlanEnum.STATUS.getAttr());
                statusCondition.setFieldType(CommunicatePlanEnum.STATUS.getFieldType());
                statusCondition.setName(CommunicatePlanEnum.STATUS.getAttrName());
                statusCondition.setSymbol(ConditionEnum.IN.getSymbol());
                statusCondition.setValue(Arrays.asList(CommunicatePlanStatusEnum.NO_FOLLOW.getCode().toString(),CommunicatePlanStatusEnum.DELAY.getCode().toString()));
                delayCondition.setAttr(CommunicatePlanEnum.IS_DELAY.getAttr());
                delayCondition.setFieldType(CommunicatePlanEnum.IS_DELAY.getFieldType());
                delayCondition.setName(CommunicatePlanEnum.IS_DELAY.getAttrName());
                delayCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                delayCondition.setValue(Collections.singletonList(1));
                conditionsEntityExtList.add(statusCondition);
                conditionsEntityExtList.add(delayCondition);
                break;
            default:
                break;
        }
        return conditionsEntityExtList;
    }

    /**
     * 设置查询数据条件
     * @param communicatePlanDTO 参数
     * @param conditionsEntityExtList 查询条件
     * @return 用户id
     * @throws XbbException
     */
    @Override
    public Set<String> setDataCondition(CommunicatePlanDTO communicatePlanDTO, List<ConditionsEntityExt> conditionsEntityExtList) throws XbbException{
        List<String> userIdList = getUserIdList(communicatePlanDTO);
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",communicatePlanDTO.getCorpid());
        map.put("userIdIn",userIdList);
        map.put("del",0);
        List<CommunicatePlanUserEntity> planUserList = communicatePlanUserModel.findEntitys(map);
        Set<String> userSet = new LinkedHashSet<>();
        Set<Long> planIdSet = new LinkedHashSet<>();
        for (CommunicatePlanUserEntity planUser : planUserList){
            Long planId = planUser.getDataId();
            userSet.add(planUser.getUserId());
            planIdSet.add(planId);
        }
        if (planIdSet.isEmpty()){
            planIdSet.add(-1L);
        }
        //不优雅
        communicatePlanDTO.setTotal(planIdSet.size());
        //可以看到得数据
        ConditionsEntityExt userCondition = new ConditionsEntityExt();
        userCondition.setAttr(FieldTypeEnum.DATAID.getAlias());
        userCondition.setFieldType(FieldTypeEnum.DATAID.getType());
        userCondition.setName(FieldTypeEnum.DATAID.getDescription());
        userCondition.setSymbol(ConditionEnum.IN.getSymbol());
        userCondition.setValue(new ArrayList<>(planIdSet));
        UserVO loginUser = communicatePlanDTO.getLoginUser();
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(loginUser,userEntity);
        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), null);
        //非老板和超管&数据权限非5添加es条件
        String pid = communicatePlanDTO.getPid();
        if ((!loginUser.isAdminOrBoss() && !Objects.equals(dataPermission, DataPermissionEnum.ALL.getCode())) || StringUtil.isNotEmpty(pid)){
            conditionsEntityExtList.add(userCondition);
        }
        return userSet;
    }

    /**
     * 获取查询的员工
     * @param communicatePlanDTO 参数
     * @return 员工idList
     * @throws XbbException
     */
    private List<String> getUserIdList(CommunicatePlanDTO communicatePlanDTO) throws XbbException{
        String userId = communicatePlanDTO.getUserId();
        String corpid = communicatePlanDTO.getCorpid();
        UserEntity userEntity = userModel.getByKey(userId,corpid);
//        List<String> useridList;
        //可见的userId
        List<String> seenUserId = new ArrayList<>();
        //分组
        Integer listGroupId = communicatePlanDTO.getListGroupId();
        listGroupId = listGroupId == null ? 0 : listGroupId;
        //TODO 丑陋
        switch (listGroupId) {
            case 0:
                //全部,不可以看到离职
                Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), null);
                seenUserId = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ZERO,false);
                break;
            case 21:
                //我的
                seenUserId.add(userId);
                break;
            case 22:
                //下属,不可以看到离职
                Integer permission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), null);
                seenUserId = userModel.getSubIdListByDataPermission(permission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ZERO,true);
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        //选择的userId
        List<String> checkUserIdIn = new ArrayList<>();
        if(Objects.equals(communicatePlanDTO.getTreeType(),TREE_TYPE_STAFF)){
            checkUserIdIn.add(communicatePlanDTO.getPid());
            seenUserId.retainAll(checkUserIdIn);
        }else if(Objects.equals(communicatePlanDTO.getTreeType(),TREE_TYPE_DEPARTMENT) && !Objects.equals(communicatePlanDTO.getPid(),"1")){
            //如果是部门的情况下，要排除全公司的情况
            Long depId =StringUtil.StringToLong(communicatePlanDTO.getPid());
            checkUserIdIn = userModel.getUserIdsRecursionDep(Collections.singletonList(depId),corpid);
            seenUserId.retainAll(checkUserIdIn);
        }else{
//            useridList=new ArrayList<>(seenUserId);
        }
        if(seenUserId.isEmpty()) {
            //TODO haibin.zhang 这边应该处理一下
            seenUserId.add("-1");
        }
        return seenUserId;
    }

    /**
     * es查询
     * @param communicatePlanDTO 公司id
     * @param conditionsEntityExtList 查询条件
     * @return 访客计划数据
     * @throws XbbException
     */
    private XbbAggregatedPage<PaasFormDataEntityExt> esList(CommunicatePlanDTO communicatePlanDTO, List<ConditionsEntityExt> conditionsEntityExtList, Integer page, Integer size) throws XbbException{
        String corpid = communicatePlanDTO.getCorpid();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        EsUtil.parseCondition(boolQueryBuilder,conditionsEntityExtList,null, corpid, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        sourceBuilder.sort(new FieldSortBuilder("data." +  CommunicatePlanEnum.COMMUNICATE_TIME.getAttr()).order(SortOrder.ASC));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getType()));
        sourceBuilder.query(boolQueryBuilder);
        EsUtil.setFieldList(sourceBuilder,communicatePlanDTO.getFieldList());
        PageRequest pageRequest;
        try {
            pageRequest = EsUtil.setPage(sourceBuilder, page, size);
        }catch (Exception e){
            LOG.error("访客计划统计1",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            LOG.error("访客计划统计2",JSONObject.toJSONString(searchRequest));
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return esEntities;
    }

    /**
     * es聚合查询
     * @param corpid 公司id
     * @param conditionsEntityExtList 筛选条件
     * @param startTime 分桶开始时间
     * @param endTime 分桶结束时间
     * @param communicatePlanDTO
     * @return 聚合结果
     * @throws XbbException
     */
    private JSONObject esDayList(String corpid, List<ConditionsEntityExt> conditionsEntityExtList,Long startTime,Long endTime,CommunicatePlanDTO communicatePlanDTO) throws XbbException{
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        EsUtil.parseCondition(boolQueryBuilder,conditionsEntityExtList,null,corpid,XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
        // 自行拼接父子文档查询参数
        List<String> userIdList = getUserIdList(communicatePlanDTO);
        Set<String> userSet = new LinkedHashSet<>(userIdList);
        BoolQueryBuilder teamQueryBuilder = boolQuery();
        teamQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        teamQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        HasChildQueryBuilder hasChildQueryBuilder = JoinQueryBuilders.hasChildQuery(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN_TEAM.getType(), teamQueryBuilder, ScoreMode.Max);
        String attr = CommunicatePlanTeamEnum.getEsAttr(CommunicatePlanTeamEnum.USER_ID);
        teamQueryBuilder.filter(termsQuery(attr, new ArrayList<>(userSet)));
        boolQueryBuilder.filter(hasChildQueryBuilder);
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel() ));
        nativeSearchQueryBuilder.withSort(new FieldSortBuilder("data." +  CommunicatePlanEnum.COMMUNICATE_TIME.getAttr()).order(SortOrder.ASC));
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
//        nativeSearchQueryBuilder.withIndices(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getIndex()).withTypes(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getType());
        List<IndexBoost> indexBoosts = new ArrayList<>(1);
        indexBoosts.add(new IndexBoost(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getIndex(),0));
        nativeSearchQueryBuilder.withIndicesBoost(indexBoosts);
        ValuesSourceAggregationBuilder<org.elasticsearch.search.aggregations.support.ValuesSource, DateHistogramAggregationBuilder> dateHistogramAggregation = AggregationBuilders.dateHistogram("aggs01").field("data." + CommunicatePlanEnum.COMMUNICATE_TIME.getAttr());
        dateHistogramAggregation.timeZone(ZoneId.systemDefault());
        dateHistogramAggregation.format("yyyy-MM-dd");
        //设置extendedBounds
        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
        String min = DateTimeUtil.getStringEpochSecond(startTime, sdfDate);
        //比如2017全年应该是2017-01-01到2017-12-31，如果是2018-01-01会返回13个桶
        String max = DateTimeUtil.getStringEpochSecond(endTime-1, sdfDate);
        ExtendedBounds extendedBounds = new ExtendedBounds(min, max);
        ((DateHistogramAggregationBuilder) dateHistogramAggregation).extendedBounds(extendedBounds);
        //设置dateHistogramInterval
        DateHistogramInterval dateHistogramInterval = DateHistogramInterval.DAY;
        ((DateHistogramAggregationBuilder) dateHistogramAggregation).calendarInterval(dateHistogramInterval);
        return esHelper.elasticAggs4NoBuckets2Object(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN, boolQueryBuilder, dateHistogramAggregation);
    }


    /**
     * 获取访客计划统计
     *
     * @param communicatePlanDTO
     * @return
     * @throws XbbException
     */
    private List<PaasFormDataEntityExt> getStatisticsEsList(CommunicatePlanDTO communicatePlanDTO, List<ConditionsEntityExt> conditionsEntityExtList) throws XbbException{

        //创建时间(时刻)
        ConditionsEntityExt dateCondition = new ConditionsEntityExt();
        Integer dateInt;
        try {
            String date = communicatePlanDTO.getDate();
            dateInt = StringUtil.isEmpty(date) ? DateUtil.getTodayInt() : DateUtil.getInt(date, new SimpleDateFormat("yyyy-MM-dd"));
        }catch (Exception e){
            throw new XbbException(CommuicatePlanErrorCodeEnum.API_ERROR_214006);
        }
        dateCondition.setAttr(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr());
        dateCondition.setFieldType(CommunicatePlanEnum.COMMUNICATE_TIME.getFieldType());
        dateCondition.setSymbol(ConditionEnum.RANGE.getSymbol());
        dateCondition.setValue(Arrays.asList(dateInt,dateInt + TimeConstant.SECONDS_PER_DAY));
        conditionsEntityExtList.add(dateCondition);
        List<PaasFormDataEntityExt> list;
        XbbAggregatedPage<PaasFormDataEntityExt> result = esList(communicatePlanDTO, conditionsEntityExtList,1, SizeConstant.PAGE_SIZE);
        list = result.getContent();
        return list;
    }

    @Override
    public void dataConsistencyUpdateCustomer(String corpid, Long customerId, String customerName) throws XbbException {
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery(CommunicatePlanEnum.getEsAttr4Keyword(CommunicatePlanEnum.LINK_CUSTOMER), customerId));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("ids", ids);
            param.put("del", 0);
            List<CommunicatePlanEntityExt> communicatePlanEntityList = communicatePlanModel.findEntitys(param);

            if (Objects.nonNull(communicatePlanEntityList) && !communicatePlanEntityList.isEmpty()) {
                List<CommunicatePlanUpdateDTO> communicatePlanUpdateDTOList = new ArrayList<>();
                for (CommunicatePlanEntityExt communicatePlanEntityExt : communicatePlanEntityList) {
                    CommunicatePlanUpdateDTO communicatePlanUpdateDTO = new CommunicatePlanUpdateDTO();
                    communicatePlanUpdateDTO.setId(communicatePlanEntityExt.getId());
                    JSONObject data = new JSONObject();
                    data.put(CommunicatePlanEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), customerName);
                    communicatePlanUpdateDTO.setData(data);
                    communicatePlanUpdateDTOList.add(communicatePlanUpdateDTO);
                }
                CommunicatePlanUpdateBatchDTO communicatePlanUpdateBatchDTO = new CommunicatePlanUpdateBatchDTO();
                communicatePlanUpdateBatchDTO.setCorpid(corpid);
                communicatePlanUpdateBatchDTO.setCommunicatePlanUpdateList(communicatePlanUpdateDTOList);
                updateBatch(communicatePlanUpdateBatchDTO);
            }
        } catch (Exception e) {
            LOG.error("CommunicatePlanServiceImpl.dataConsistencyUpdateCustomer 出错， corpid=" + corpid + "  customerId=" + customerId + "  customerName=" + customerName, e);
        }
    }

    @Override
    public CommunicatePlanUpdateBatchVO updateBatch(CommunicatePlanUpdateBatchDTO communicatePlanUpdateBatchDTO) throws XbbException {
        CommunicatePlanUpdateBatchVO communicatePlanUpdateBatchVO = new CommunicatePlanUpdateBatchVO();
        try {
            String corpid = communicatePlanUpdateBatchDTO.getCorpid();
            List<UpdateDataEntity> updateList = new ArrayList<>();
            List<CommunicatePlanUpdateDTO> communicatePlanUpdateList = communicatePlanUpdateBatchDTO.getCommunicatePlanUpdateList();
            if (Objects.nonNull(communicatePlanUpdateList) && !communicatePlanUpdateList.isEmpty()) {
                communicatePlanUpdateList.forEach((item)->{
                    updateList.add(ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid));
                });
            }
            if (!updateList.isEmpty()) {
                communicatePlanModel.updateBatch(updateList, corpid);
            }
        } catch (Exception e) {
            LOG.error("CommunicatePlanServiceImpl.updateBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return communicatePlanUpdateBatchVO;
    }

    @Override
    public ListAppVO formatCommunicatePlanAppList(CommunicatePlanDTO communicatePlanDTO, List<PaasFormDataEntityExt> esEntities, Integer totalCount) throws XbbException{
        List<AppListPojo> appListPojos = new ArrayList<>();
        String statusAttr = CommunicatePlanEnum.STATUS.getAttr();
        String statusAttrName = CommunicatePlanEnum.STATUS.getAttrName();
        String status = "";
        for (PaasFormDataEntityExt entity : esEntities) {
            JSONObject data = entity.getData();
            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<SummaryDataPoJo> lableList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);

            status = ItemUtil.parseItemPoJoFromFormData2String(data, statusAttr, "");
            if (Objects.equals(status, CommunicatePlanStatusEnum.DELAY.getAlias())) {
                String delayCause = getCause(data, CommunicatePlanEnum.DELAY_CAUSE.getAttr(), "");
                String delayMemo = FastJsonHelper.getStringOrDefaultFromFormData(data, CommunicatePlanEnum.DELAY_MEMO.getAttr(), "");
                summaryList.add(commonHelp.setSummary(CommunicatePlanEnum.DELAY_CAUSE.getAttrName(), delayCause));
                summaryList.add(commonHelp.setSummary(CommunicatePlanEnum.DELAY_MEMO.getAttrName(), delayMemo));
            }
            CommunicatePlanStatusEnum byAlias = CommunicatePlanStatusEnum.getByAlias(status);
            if (byAlias != null) {
                status = byAlias.getCode();
            }
            appListPojos.add(new AppListPojo(entity.getId(), titleList, summaryList, null, lableList, status, entity.getAppId(), entity.getMenuId(), entity.getFormId()));
        }
        ListAppVO listAppVO = new ListAppVO();
        listAppVO.setList(appListPojos);
        listAppVO.setTotalCount(totalCount);
        return  listAppVO;
    }

    private String getCause(JSONObject data, String attr, String defaultValue) throws XbbException {
        String result = null;
        if (data == null || attr == null) {
            return defaultValue;
        }
        try {
            Object value = data.get(attr);
            if (value == null) {
                return defaultValue;
            } else if (value instanceof ItemPoJo) {
                result = ((ItemPoJo) value).getText();
            } else {
                result = data.getString(attr);
            }
            return Objects.isNull(result) ? defaultValue : result;
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
    }

    @Override
    public void afterSaveForWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long id = newPaasFormDataEntity.getId();
        String corpid = newPaasFormDataEntity.getCorpid();
        String userId = saasFormSaveDTO.getUserId();
        JSONObject newData = newPaasFormDataEntity.getData();
        Long newCustomerId = FastJsonHelper.getLongOrDefaultFromFormData(newData, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), 0L);
        saveExecutor2CommunicatePlanUser(newData, CommunicatePlanEnum.EXECUTOR.getAttr(), CommunicatePlanEnum.EXECUTOR_LINKED_TEXT.getAttr(), newCustomerId, corpid, id, userId);
    }

    @Override
    public void afterSaveForUpdateWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long id = newPaasFormDataEntity.getId();
        String corpid = newPaasFormDataEntity.getCorpid();
        String userId = saasFormSaveDTO.getUserId();
        JSONObject newData = newPaasFormDataEntity.getData();
        Long newCustomerId = FastJsonHelper.getLongOrDefaultFromFormData(newData, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), 0L);
        saveExecutor2CommunicatePlanUser(newData, CommunicatePlanEnum.EXECUTOR.getAttr(), CommunicatePlanEnum.EXECUTOR_LINKED_TEXT.getAttr(), newCustomerId, corpid, id, userId);
    }

    /**
     * 父子文档查询参数
     * @param communicatePlanDTO
     * @param conditionsEntityExtList
     * @return
     * @throws
     * @author xingxing.xiao
     * @date 2019/09/11 23:31
     */
    @Override
    public Set<String> setTeamCondition(CommunicatePlanDTO communicatePlanDTO, List<ConditionsEntityExt> conditionsEntityExtList) throws XbbException {
        // 获取查询的员工
        List<String> userIdList = getUserIdList(communicatePlanDTO);
        Set<String> userSet = new LinkedHashSet<>(userIdList);
        ConditionsEntityExt teamConditionsEntityExt = new ConditionsEntityExt(FieldTypeEnum.TEAM_USER.getAlias(), null, FieldTypeEnum.TEAM_USER.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(userSet));
        conditionsEntityExtList.add(teamConditionsEntityExt);
        return userSet;
    }

    /**
     * 访客计划员工统计特殊处理
     *
     * @param communicatePlanUserEntityList 执行人
     * @param communicatePlanDTO 统计dto
     * @author long.rao
     * @date 2019-09-25 15:58
     */
    private List<CommunicatePlanUserEntity> handlePlanUser(List<CommunicatePlanUserEntity> communicatePlanUserEntityList, CommunicatePlanDTO communicatePlanDTO) {
        if (communicatePlanUserEntityList.isEmpty()) {
            return new ArrayList<>();
        }
        List<CommunicatePlanUserEntity> showUserList = new ArrayList<>();
        String userId = communicatePlanDTO.getUserId();
        //分组
        Integer listGroupId = communicatePlanDTO.getListGroupId();
        listGroupId = listGroupId == null ? 0 : listGroupId;
        for (CommunicatePlanUserEntity userEntity : communicatePlanUserEntityList) {
            if (Objects.equals(listGroupId, 21) && !Objects.equals(userEntity.getUserId(), userId)) {
                // 分组为我执行的时，只展示我自己
                continue;
            }
            showUserList.add(userEntity);
        }
        return showUserList;
    }

    @Override
    public FormDataAddGetVO hasPlanFinish(HasCommunicatePlanDTO hasCommunicatePlanDTO) throws XbbException {
        FormDataAddGetVO formDataAddGetVO = new FormDataAddGetVO();
        JSONObject saasObj = new JSONObject();
        if (Objects.equals(hasCommunicatePlanDTO.getSourceBusinessType(), XbbRefTypeEnum.COMMUNICATE_PLAN.getCode())) {
            // 访客计划详情页跟进记录tab创建了跟进记录，保存时会自动完成该访客计划，所以后面不用弹出快捷完成访客计划弹窗
            saasObj.put("finishPlan", false);
            formDataAddGetVO.setSaasObj(saasObj);
            return formDataAddGetVO;
        }

        List<ConditionsEntityExt> conditions = hasCommunicatePlanDTO.getConditions();

        ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
        conditionsEntityExt.setAttr(CommunicatePlanEnum.LINK_CUSTOMER.getAttr());
        conditionsEntityExt.setFieldType(FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
        conditionsEntityExt.setName("");
        conditionsEntityExt.setSubAttr("");
        conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
        List<Object> valueList = new ArrayList<>();
        valueList.add(hasCommunicatePlanDTO.getParentId());
        conditionsEntityExt.setValue(valueList);
        conditions.add(conditionsEntityExt);

        List<Long> dataIdList = communicatePlanUserModel.getDataIdList(hasCommunicatePlanDTO.getCorpid(), Collections.singletonList(hasCommunicatePlanDTO.getUserId()));
        conditions.add(new ConditionsEntityExt(FieldTypeEnum.DATAID.getAlias(), "", FieldTypeEnum.DATAID.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(dataIdList)));

        FormDataListDTO formDataListDTO = new FormDataListDTO();
        BeanUtil.copyProperties(hasCommunicatePlanDTO, formDataListDTO);

        formDataListDTO.getConditions().add(new ConditionsEntityExt(FieldTypeEnum.FLOW_STATUS.getAlias(),"", FieldTypeEnum.FLOW_STATUS.getType(),ConditionEnum.IN.getSymbol(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        // 只能搜到没有删除的数据
        formDataListDTO.setDel(0);

        formDataListDTO.setSimple(false);
        formDataListDTO.setFieldList(new ArrayList<>());
        formDataListDTO.setSaasMark(hasCommunicatePlanDTO.getSaasMark());
        formDataListDTO.setSearchSubForm(false);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(formDataListDTO.getCorpid(), formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
        PaasFormDataEsListVO formDataListVO = paasFormDataEsModel.list(formDataListDTO, indexTypeEnum);
        List<PaasFormDataEntityExt> paasFormDataESList = formDataListVO.getPaasFormDataESList();
        if (!paasFormDataESList.isEmpty()) {
            saasObj.put("linkParentId", hasCommunicatePlanDTO.getParentId());
            saasObj.put("parentBuinessType", XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
            saasObj.put("finishPlan", true);
        } else {
            saasObj.put("finishPlan", false);
        }
        formDataAddGetVO.setSaasObj(saasObj);
        return formDataAddGetVO;
    }
    /**
     * 保存执行人到计划协同团队表
     *
     * @param data               数据
     * @param executor           执行人属性
     * @param executorLinkedText 执行人关联属性
     * @param linkCustomerId     关联客户id
     * @param corpid             公司id
     * @param id                 访客计划id
     * @param userId             员工id
     * @author feng.zheng
     * @date 2019/2/14 22:06
     */
    @Override
    public List<String> saveExecutor2CommunicatePlanUser(JSONObject data, String executor, String executorLinkedText, Long linkCustomerId, String corpid, Long id, String userId) throws XbbException {
        //执行人员
//        List<String> thisUserIds = new ArrayList<>();
        Set<String> thisUserIds = new HashSet<>();
        if (data == null || executor == null || executorLinkedText == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        try {
            boolean isManager = false;
            boolean isCooper = false;
            boolean isCustom = false;
            JSONArray checkArray = data.getJSONArray(executor);
            for (Object obj : checkArray) {
                Integer check = Integer.parseInt(obj.toString());
                if (Objects.equals(check, ExecutorCheckBoxEnum.MAIN_USER_CHECK.getCode())) {
                    isManager = true;
                }
                if (Objects.equals(check, ExecutorCheckBoxEnum.COOPER_USER_CHECK.getCode())) {
                    isCooper = true;
                }
                if (Objects.equals(check, ExecutorCheckBoxEnum.CUSTOM_CHECK.getCode())) {
                    isCustom = true;
                }
            }
            Map<Long, List<String>> customerMainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> customerCoopUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (isManager || isCooper) {
                //查找所有客户的协同团队
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("del", 0);
                param.put("customerId", linkCustomerId);
                param.put("corpid", corpid);
                List<CustomerUserEntity> customerUserList = customerUserModel.findEntitys(param);
                for (CustomerUserEntity customerUserEntity : customerUserList) {
                    String cUserId = customerUserEntity.getUserId();
                    Integer isMain = customerUserEntity.getIsMain() == null ? 0 : customerUserEntity.getIsMain();
                    List<String> mainUser = customerMainUserMap.get(linkCustomerId) == null ? new ArrayList<>() : customerMainUserMap.get(linkCustomerId);
                    List<String> coopUser = customerCoopUserMap.get(linkCustomerId) == null ? new ArrayList<>() : customerCoopUserMap.get(linkCustomerId);
                    if (isMain == 1) {
                        mainUser.add(cUserId);
                    } else if (isMain == 0) {
                        coopUser.add(cUserId);
                    }
                    customerMainUserMap.put(linkCustomerId, mainUser);
                    customerCoopUserMap.put(linkCustomerId, coopUser);
                }
            }

            JSONArray userArray = data.getJSONArray(executorLinkedText);
            if (isCustom && userArray != null) {
                for (Object userObj : userArray) {
                    String customUserId = userObj.toString();
                    thisUserIds.add(customUserId);
                }
            }
            // 负责人
            if (isManager) {
                List<String> thisMainUsers = customerMainUserMap.get(linkCustomerId);
                if (thisMainUsers != null) {
                    thisUserIds.addAll(thisMainUsers);
                }
            }
            // 协同人
            if (isCooper) {
                List<String> thisCoopUsers = customerCoopUserMap.get(linkCustomerId);
                if (thisCoopUsers != null) {
                    thisUserIds.addAll(thisCoopUsers);
                }
            }
            // 保存
            if (!thisUserIds.isEmpty()) {
                //添加执行人
                Map<String, Object> userParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                userParam.clear();
                userParam.put("del", 0);
                userParam.put("corpid", corpid);
                userParam.put("userIdIn", thisUserIds);
                List<UserEntity> users = userModel.findEntitys(userParam);
                List<CommunicatePlanUserEntity> CommunicatePlanUserEntityList = new ArrayList<>();
                for (UserEntity user : users) {
                    CommunicatePlanUserEntity planUser = new CommunicatePlanUserEntity();
                    planUser.setCorpid(corpid);
                    planUser.setDataId(id);
                    planUser.setUserId(user.getUserId());
                    planUser.setUserName(user.getName());
                    planUser.setUserAvatar(user.getAvatar());
                    planUser.setIsCreator(userId.equals(user.getUserId()) ? 1 : 0);
                    CommunicatePlanUserEntityList.add(planUser);
                }
                communicatePlanUserModel.insertBatch(CommunicatePlanUserEntityList);
            }
        } catch (Exception e) {
            LOG.error("保存执行人到计划协同团队表出错:",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
        return new ArrayList<>(thisUserIds);
    }
    /**
     * 设置范围筛选
     *
     * @param communicatePlanDTO
     * @param conditionsEntityExtList
     * @throws
     * @author long.rao
     * @date 2020-03-03 10:49
     */
    private void rangeScreen(CommunicatePlanDTO communicatePlanDTO, List<ConditionsEntityExt> conditionsEntityExtList) throws XbbException {
        if (Objects.equals(communicatePlanDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
            return;
        }
        JSONObject rangeScreen = communicatePlanDTO.getRangeScreen();
        if (Objects.isNull(rangeScreen) || Objects.isNull(rangeScreen.get(RangeScreenConstant.TYPE)) || StringUtil.isEmpty(rangeScreen.getString(RangeScreenConstant.TYPE)) || Objects.isNull(rangeScreen.get(RangeScreenConstant.VALUE))) {
            return;
        }
        String type;
        List<String> values;
        try {
            type = rangeScreen.getString(RangeScreenConstant.TYPE);
            values = rangeScreen.getJSONArray(RangeScreenConstant.VALUE).toJavaList(String.class);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), "customerCommunicateServiceimpl.rangeScreen中的commonFilter参数错误");
        }
        if (CollectionsUtil.isEmpty(values)) {
            return;
        }
        if (Objects.equals(type, RangeScreenConstant.DEPARTMENT)) {
            List<Long> deptIds = new ArrayList<>(values.size());
            values.forEach(item -> deptIds.add(Long.valueOf(item)));
            values = userModel.getUserIdsRecursionDep(deptIds, communicatePlanDTO.getCorpid(), 1, true);
        }
        ConditionsEntityExt teamConditionsEntityExt = new ConditionsEntityExt(FieldTypeEnum.TEAM_USER.getAlias(), null, FieldTypeEnum.TEAM_USER.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(values));
        conditionsEntityExtList.add(teamConditionsEntityExt);
    }

    /**
     * 删除访客计划提醒
     *
     * @param corpid
     * @param idIn
     */
    private void deletePush(String corpid, List<Long> idIn) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put(BasicConstant.BUSINESS_TYPE, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
        // 当前时间大于10秒，防止有消息又在消息队列中
        param.put("startPushTime", DateTimeUtil.getInt() + BasicConstant.TEN);
        param.put("refIdIn", idIn);
        List<PushEntity> list = pushModel.findEntitys(param);

        if (CollectionsUtil.isEmpty(list)) {
            return;
        }
        List<Long> pushIdIn = new ArrayList<>();
        list.forEach(item -> pushIdIn.add(item.getId()));
        try {
            pushModel.deleteByIdIn(pushIdIn, corpid);
        } catch (Exception e) {
            LOG.error("delete communicatePlan push error", e.getMessage());
        }

    }

}
